package com.sz.app.edi.rest.edi.order;

import com.sz.app.edi.base.entity.SynCompanyAccount;
import com.sz.app.edi.base.service.SynCompanyAccountService;
import com.sz.app.edi.constants.EdiErrorCodes;
import com.sz.app.edi.exception.EdiException;
import com.sz.app.edi.rest.edi.base.EventBody;
import com.sz.app.edi.rest.edi.base.EventHead;
import com.sz.app.edi.rest.edi.base.LogisticsRequest;
import com.sz.app.edi.rest.edi.base.Response;
import com.sz.app.edi.rest.edi.order.dto.CusOrderDto;
import com.sz.app.edi.rest.edi.order.dto.OrdDetailFeeDto;
import com.sz.app.edi.rest.edi.order.dto.OrdServiceDto;
import com.sz.app.edi.rest.edi.order.dto.WaybillNosDto;
import com.sz.app.edi.service.order.CusOrderService;
import com.sz.biz.app.web.BaseController;
import com.sz.biz.common.base.entity.FeeType;
import com.sz.biz.common.base.service.FeeTypeService;
import com.sz.biz.common.utils.OrderMake;
import com.sz.biz.logistics.core.entity.Product;
import com.sz.biz.logistics.core.entity.Service;
import com.sz.biz.logistics.core.service.ProductService;
import com.sz.biz.logistics.core.service.ServiceService;
import com.sz.biz.logistics.ord.constants.OrderConstants;
import com.sz.biz.logistics.ord.entity.OrdServiceBill;
import com.sz.biz.logistics.ord.service.OrdOrderService;
import com.sz.biz.logistics.ord.service.OrdServiceBillService;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.JsonUtils;
import com.sz.common.base.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * Function: edi下单controller
 * Author: hpeng.wang.<br>
 * Date: 2017-06-23 16:08:00.
 */
@RestController
@RequestMapping("${out}/order/orders")
@Api(description = " ", tags = "051-001、EDI-订单-下单")
public class CusOrderController extends BaseController {
    @Autowired
    private CusOrderService cusOrderService;

    @Autowired
    private SynCompanyAccountService accountService;

    @Autowired
    private OrdOrderService ordOrderService;

    @Autowired
    private OrdServiceBillService ordServiceBillService;

    /**
     * 产品service
     */
    @Autowired
    private ProductService productService;

    /**
     * 服务service
     */
    @Autowired
    private ServiceService serviceService;

    /**
     * 费用service
     */
    @Autowired
    private FeeTypeService feeTypeService;

    /**
     * 下单
     */
    @ApiOperation(value = "新增", notes = "新增订单")
    @RequestMapping(value = "", method = {RequestMethod.POST})
    public ResultDto save(@RequestBody @ApiParam(value = "要保存的数据", required = true) @Validated LogisticsRequest dto) {

        EventHead eventHead = dto.getEventHead();
        SynCompanyAccount companyAccount = accountService.findByToken(eventHead.getToken());
        Object object;
        try {
            object = JsonUtils.toObject(JsonUtils.toJSONString(dto.getEventBody().getData()), CusOrderDto.class);
        } catch (Exception e) {
            logger.error("下单时解析json格式异常：", e);
            throw Exceptions.bizException(EdiErrorCodes.ERROR_EDI_JSON_VALID);
        }
        CusOrderDto orderDto;
        if (object instanceof CusOrderDto) {
            orderDto = (CusOrderDto) object;
            orderDto.setCustomerId(companyAccount.getBizId());
            orderDto.setCusUserId(companyAccount.getBizAccountId());
            if (StringUtils.isEmpty(orderDto.getExternalNo())) {
                orderDto.setExternalNo(OrderMake.generateCusExternalNo());
            }
        } else {
            throw Exceptions.bizException(EdiErrorCodes.ERROR_ARGUMENT);
        }

        //客户系统的订单
        orderDto.setType(OrderConstants.OrderPlatform.ORDER_EDI_API);
        String orderNo = cusOrderService.saveRestOrder(orderDto);

        //返回信息
        ResultDto result = getOperateSuccessDto(null);
        result.setData(orderNo);
        return result;
    }


    /**
     * 订单费用明细
     *
     * @param logisticsRequest 订单编号集合对象
     * @return resp 请求响应
     * @author Fengwj
     * @date 2017/12/27
     */
    @ApiOperation(value = "订单费用明细", notes = "订单费用明细")
    @RequestMapping(value = "/fee", method = {RequestMethod.POST})
    public Response detailedFee(HttpServletRequest request,
                                @RequestBody @ApiParam(value = "订单编号集合对象", required = true) LogisticsRequest logisticsRequest) {

        //返回信息
        Response resp = new Response();
        //接受入参
        EventBody body = logisticsRequest.getEventBody();

        //获取请求的运单号
        WaybillNosDto waybillNosDto = JsonUtils.toObject(JsonUtils.toJSONString(body.getData()), WaybillNosDto.class);
        //入参验证
        if (CollectionUtils.isEmpty(waybillNosDto.getWaybillNos())) {
            throw new EdiException(EdiErrorCodes.ERROR_EDI_ORD_WAYBILLNO_ERROR.getCode(), "传入的运单号错误！");
        }

        //根据运单号批量获取订单号
        Map<String, String> orderNoMap = ordOrderService.findNoMapByWaybillNos(waybillNosDto.getWaybillNos());
        List<String> orderNos = new ArrayList<>();
        orderNos.addAll(orderNoMap.values());
        //订单号没有查到
        if (CollectionUtils.isEmpty(orderNos)) {
            resp.setData(null);
            return resp;
        }

        //客户id
        Integer customerId = Integer.parseInt(request.getAttribute("bizId").toString());
        //根据订单号集合查询所需数据
        List<OrdServiceBill> ordServiceBills = ordServiceBillService.getByOrderNos(orderNos, customerId);
        //详情信息没有查到
        if (CollectionUtils.isEmpty(ordServiceBills)) {
            resp.setData(null);
            return resp;
        }

        //返回所需对象
        List<OrdDetailFeeDto> ordDetailFeeDtos = new ArrayList<>();

        //循环封装数据
        for (String key : orderNoMap.keySet()) {
            //订单号
            String value = orderNoMap.get(key);
            //服务费用信息
            OrdDetailFeeDto ordDetailFeeDto = new OrdDetailFeeDto();
            List<OrdServiceDto> ordServiceDtos = new ArrayList<>();
            BigDecimal countAmount = new BigDecimal(0);

            for (OrdServiceBill bill : ordServiceBills) {
                //只处理与当前订单号相同的数据
                if (value.equals(bill.getOrderNo())) {
                    if (StringUtils.isEmpty(ordDetailFeeDto.getWaybillNo())) {
                        //设置运单号
                        ordDetailFeeDto.setWaybillNo(key);
                        //获取产品名称
                        String productName = "";
                        Product product = productService.findById(bill.getProductId());
                        if (null != product) {
                            productName = product.getName();
                        }
                        ordDetailFeeDto.setProductName(productName);
                        //计费时间
                        ordDetailFeeDto.setBillTime(bill.getBillTime());
                    }
                    //获取服务id
                    OrdServiceDto ordServiceDto = new OrdServiceDto();
                    Integer serviceId = bill.getServiceId();
                    ordServiceDto.setServiceId(serviceId);
                    //获取服务名称
                    String serviceName = "";
                    Service service = serviceService.findById(serviceId);
                    if (null != service) {
                        serviceName = service.getName();
                    }
                    ordServiceDto.setServiceName(serviceName);
                    //获取费用名称
                    String feeTypeName = "";
                    FeeType feeType = feeTypeService.findById(bill.getFeeTypeId());
                    if (null != feeType) {
                        feeTypeName = feeType.getName();
                    }
                    ordServiceDto.setFeeTypeName(feeTypeName);
                    //费用金额
                    ordServiceDto.setFeeAmount(bill.getCustCurrencyAmount());
                    //订单总金额
                    countAmount = countAmount.add(bill.getCustCurrencyAmount());
                    //货币单位
                    ordDetailFeeDto.setCurrencyCode(bill.getCustCurrencyCode());

                    ordServiceDtos.add(ordServiceDto);
                    ordDetailFeeDto.setOrdServiceDtos(ordServiceDtos);
                }
            }
            //订单总金额
            ordDetailFeeDto.setAllAmount(countAmount);

            ordDetailFeeDtos.add(ordDetailFeeDto);
        }

        resp.setData(ordDetailFeeDtos);
        return resp;
    }
}
